/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.activiti.editor.language.json.converter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.model.*;
import org.activiti.editor.language.json.converter.util.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * @author Tijs Rademakers
 */

//增加节点是否可以跳过的属性
public class UserTaskJsonConverter extends BaseBpmnJsonConverter {


    public static void fillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
            Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {

        fillJsonTypes(convertersToBpmnMap);
        fillBpmnTypes(convertersToJsonMap);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put(STENCIL_TASK_USER, UserTaskJsonConverter.class);
    }

    public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(UserTask.class, UserTaskJsonConverter.class);
    }

    @Override
    protected String getStencilId(BaseElement baseElement) {
        return STENCIL_TASK_USER;
    }

    @Override
    protected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement) {
        UserTask userTask = (UserTask) baseElement;
        String assignee = userTask.getAssignee();
        String owner = userTask.getOwner();

        if (StringUtils.isNotEmpty(assignee) || StringUtils.isNotEmpty(owner) || CollectionUtils.isNotEmpty(userTask.getCandidateUsers()) ||
                CollectionUtils.isNotEmpty(userTask.getCandidateGroups())) {

            ObjectNode assignmentNode = objectMapper.createObjectNode();
            ObjectNode assignmentValuesNode = objectMapper.createObjectNode();

            if (StringUtils.isNotEmpty(assignee)) {
              assignmentValuesNode.put(PROPERTY_USERTASK_ASSIGNEE, assignee);
            }

            if (StringUtils.isNotEmpty(owner)) {
              assignmentValuesNode.put(PROPERTY_USERTASK_OWNER, owner);
            }

            if (CollectionUtils.isNotEmpty(userTask.getCandidateUsers())) {
                ArrayNode candidateArrayNode = objectMapper.createArrayNode();
                for (String candidateUser : userTask.getCandidateUsers()) {
                    ObjectNode candidateNode = objectMapper.createObjectNode();
                    candidateNode.put("value", candidateUser);
                    candidateArrayNode.add(candidateNode);
                }
                assignmentValuesNode.put(PROPERTY_USERTASK_CANDIDATE_USERS, candidateArrayNode);
            }

            if (CollectionUtils.isNotEmpty(userTask.getCandidateGroups())) {
                ArrayNode candidateArrayNode = objectMapper.createArrayNode();
                for (String candidateGroup : userTask.getCandidateGroups()) {
                    ObjectNode candidateNode = objectMapper.createObjectNode();
                    candidateNode.put("value", candidateGroup);
                    candidateArrayNode.add(candidateNode);
                }
                assignmentValuesNode.put(PROPERTY_USERTASK_CANDIDATE_GROUPS, candidateArrayNode);
            }

            assignmentNode.put("assignment", assignmentValuesNode);
            propertiesNode.put(PROPERTY_USERTASK_ASSIGNMENT, assignmentNode);
        }

        if (userTask.getPriority() != null) {
            setPropertyValue(PROPERTY_USERTASK_PRIORITY, userTask.getPriority().toString(), propertiesNode);
        }

        if (StringUtils.isNotEmpty(userTask.getFormKey())) {
            setPropertyValue(PROPERTY_FORMKEY, userTask.getFormKey(), propertiesNode);
        }

        //改过的，是否可以AA跳-刘翔宇
        List<ExtensionElement> skiptask = userTask.getExtensionElements().get("skiptask");
        if(skiptask!=null){
        	for (ExtensionElement extensionElement : skiptask) {
        		setPropertyValue("skiptask",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //节点审批人为空是否可以跳过
        List<ExtensionElement> approvalnullskiptask = userTask.getExtensionElements().get("approvalnullskiptask");
        if(approvalnullskiptask!=null){
        	for (ExtensionElement extensionElement : approvalnullskiptask) {
        		setPropertyValue("approvalnullskiptask",extensionElement.getElementText(), propertiesNode);
     	 	}
        }
        //节点跳过时审批意见
        List<ExtensionElement> skiptaskopinion = userTask.getExtensionElements().get("skiptaskopinion");
        if(skiptaskopinion!=null){
        	for (ExtensionElement extensionElement : skiptaskopinion) {
        		setPropertyValue("skiptaskopinion",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //增加属性,是否可以修改表单
        List<ExtensionElement> actModifyFrom = userTask.getExtensionElements().get("actmodifyfrom");
        if(actModifyFrom!=null){
        	for (ExtensionElement extensionElement : actModifyFrom) {
        		setPropertyValue("actmodifyfrom",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //附件是否必填
        List<ExtensionElement> filerequired = userTask.getExtensionElements().get("filerequired");
        if(filerequired!=null){
        	for (ExtensionElement extensionElement : filerequired) {
        		setPropertyValue("filerequired",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //是否可以查看审批记录
        List<ExtensionElement> actapprovalrecord = userTask.getExtensionElements().get("actapprovalrecord");
        if(actapprovalrecord!=null){
        	for (ExtensionElement extensionElement : actapprovalrecord) {
        		setPropertyValue("actapprovalrecord",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //是否可以配置审批记录查看权限
        List<ExtensionElement> actrecordpermissions = userTask.getExtensionElements().get("actrecordpermissions");
        if(actrecordpermissions!=null){
        	for (ExtensionElement extensionElement : actrecordpermissions) {
        		setPropertyValue("actrecordpermissions",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //默认抄送人
        List<ExtensionElement> ccusers = userTask.getExtensionElements().get("ccusers");
        if(ccusers!=null){
        	for (ExtensionElement extensionElement : ccusers) {
        		setPropertyValue("ccusers",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //是否可以查看流程图
        List<ExtensionElement> actapprovalpng = userTask.getExtensionElements().get("actapprovalpng");
        if(actapprovalpng!=null){
        	for (ExtensionElement extensionElement : actapprovalpng) {
        		setPropertyValue("actapprovalpng",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //是否可以ABA跳过
        List<ExtensionElement> skiptaskaba = userTask.getExtensionElements().get("skiptaskaba");
        if(skiptaskaba!=null){
        	for (ExtensionElement extensionElement : skiptaskaba) {
        		setPropertyValue("skiptaskaba",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //是否可以批量办理
        List<ExtensionElement> batch = userTask.getExtensionElements().get("batch");
        if(batch!=null){
        	for (ExtensionElement extensionElement : batch) {
        		setPropertyValue("batch",extensionElement.getElementText(), propertiesNode);
     	 	}
        }

        //是否可以加签
        List<ExtensionElement> actaddtask = userTask.getExtensionElements().get("actaddtask");
        if(actaddtask!=null){
            for (ExtensionElement extensionElement : actaddtask) {
                setPropertyValue("actaddtask",extensionElement.getElementText(), propertiesNode);
            }
        }

        //是否为结束节点
        List<ExtensionElement> endnode = userTask.getExtensionElements().get("endnode");
        if(endnode!=null){
            for (ExtensionElement extensionElement : endnode) {
                setPropertyValue("endnode",extensionElement.getElementText(), propertiesNode);
            }
        }


        //是否为投票节点
        List<ExtensionElement> isvote = userTask.getExtensionElements().get("isvote");
        if(isvote!=null){
            for (ExtensionElement extensionElement : isvote) {
                setPropertyValue("isvote",extensionElement.getElementText(), propertiesNode);
            }
        }

        //是否为下一阶段选择审批人
        List<ExtensionElement> selectapproval = userTask.getExtensionElements().get("selectapproval");
        if(selectapproval!=null){
            for (ExtensionElement extensionElement : selectapproval) {
                setPropertyValue("selectapproval",extensionElement.getElementText(), propertiesNode);
            }
        }

        //节点英文名称
        List<ExtensionElement> enusname = userTask.getExtensionElements().get("enusname");
        if(enusname!=null){
            for (ExtensionElement extensionElement : enusname) {
                setPropertyValue("enusname",extensionElement.getElementText(), propertiesNode);
            }
        }

        //节点日文名称
        List<ExtensionElement> jajpname = userTask.getExtensionElements().get("jajpname");
        if(jajpname!=null){
            for (ExtensionElement extensionElement : jajpname) {
                setPropertyValue("jajpname",extensionElement.getElementText(), propertiesNode);
            }
        }

        //节点繁体名称
        List<ExtensionElement> zhtwname = userTask.getExtensionElements().get("zhtwname");
        if(zhtwname!=null){
            for (ExtensionElement extensionElement : zhtwname) {
                setPropertyValue("zhtwname",extensionElement.getElementText(), propertiesNode);
            }
        }

        // 是否需要申请人选择审批人
        List<ExtensionElement> applychoice = userTask.getExtensionElements().get("applychoice");
        if(applychoice!=null){
            for (ExtensionElement extensionElement : applychoice) {
                setPropertyValue("applychoice",extensionElement.getElementText(), propertiesNode);
            }
        }

        // 可以查看审批意见的角色
        List<ExtensionElement> viewcommentrole = userTask.getExtensionElements().get("viewcommentrole");
        if(viewcommentrole!=null){
            for (ExtensionElement extensionElement : viewcommentrole) {
                setPropertyValue("viewcommentrole",extensionElement.getElementText(), propertiesNode);
            }
        }

        // 是否为流程结束节点
        List<ExtensionElement> endtasknode = userTask.getExtensionElements().get("endtasknode");
        if(endtasknode!=null){
            for (ExtensionElement extensionElement : endtasknode) {
                setPropertyValue("endtasknode",extensionElement.getElementText(), propertiesNode);
            }
        }

        // 是否是电子签章的签约节点
        List<ExtensionElement> electronicseal = userTask.getExtensionElements().get("electronicseal");
        if(electronicseal!=null){
            for (ExtensionElement extensionElement : electronicseal) {
                setPropertyValue("electronicseal",extensionElement.getElementText(), propertiesNode);
            }
        }


        // 审批时是否可以上传
        List<ExtensionElement> uploadfile = userTask.getExtensionElements().get("uploadfile");
        if(uploadfile!=null){
            for (ExtensionElement extensionElement : uploadfile) {
                setPropertyValue("uploadfile",extensionElement.getElementText(), propertiesNode);
            }
        }

        // 前加签出去的任务是否可以驳回
        List<ExtensionElement> addbeforetaskrejected = userTask.getExtensionElements().get("addbeforetaskrejected");
        if(addbeforetaskrejected!=null){
            for (ExtensionElement extensionElement : addbeforetaskrejected) {
                setPropertyValue("addbeforetaskrejected",extensionElement.getElementText(), propertiesNode);
            }
        }


        // 申请人选择审批人的范围(可配置角色标识，多个逗号加个)
        List<ExtensionElement> applychoicescope = userTask.getExtensionElements().get("applychoicescope");
        if(applychoicescope!=null){
            for (ExtensionElement extensionElement : applychoice) {
                setPropertyValue("applychoicescope",extensionElement.getElementText(), propertiesNode);
            }
        }

        // 表单属性获取脚本
        List<ExtensionElement> formsql = userTask.getExtensionElements().get("formsql");
        if(formsql!=null){
            for (ExtensionElement extensionElement : formsql) {
                setPropertyValue("formsql",extensionElement.getElementText(), propertiesNode);
            }
        }

        setPropertyValue(PROPERTY_USERTASK_DUEDATE, userTask.getDueDate(), propertiesNode);
        setPropertyValue(PROPERTY_USERTASK_CATEGORY, userTask.getCategory(), propertiesNode);

        addFormProperties(userTask.getFormProperties(), propertiesNode);
    }

    @Override
    protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap) {
        UserTask task = new UserTask();
        task.setPriority(getPropertyValueAsString(PROPERTY_USERTASK_PRIORITY, elementNode));
        String formKey = getPropertyValueAsString(PROPERTY_FORMKEY, elementNode);
        if (StringUtils.isNotEmpty(formKey)) {
            task.setFormKey(formKey);
        }
        task.setDueDate(getPropertyValueAsString(PROPERTY_USERTASK_DUEDATE, elementNode));
        task.setCategory(getPropertyValueAsString(PROPERTY_USERTASK_CATEGORY, elementNode));

        //增加节点属性-刘翔宇
        List<CustomProperty> customProperty = task.getCustomProperties();

        //是否可以AA跳
        CustomProperty c = new CustomProperty();
        c.setName("skiptask");
        c.setSimpleValue(getPropertyValueAsString("skiptask", elementNode));
        customProperty.add(c);

        //节点审批人为空是否可以跳过
        CustomProperty c1 = new CustomProperty();
        c1.setName("approvalnullskiptask");
        c1.setSimpleValue(getPropertyValueAsString("approvalnullskiptask", elementNode));
        customProperty.add(c1);

        //节点跳过时审批意见
        CustomProperty c2 = new CustomProperty();
        c2.setName("skiptaskopinion");
        c2.setSimpleValue(getPropertyValueAsString("skiptaskopinion", elementNode));
        customProperty.add(c2);

        //是否可以修改表单
        CustomProperty c3 = new CustomProperty();
        c3.setName("actmodifyfrom");
        c3.setSimpleValue(getPropertyValueAsString("actmodifyfrom", elementNode));
        customProperty.add(c3);

        //附件是否必填
        CustomProperty c4 = new CustomProperty();
        c4.setName("filerequired");
        c4.setSimpleValue(getPropertyValueAsString("filerequired", elementNode));
        customProperty.add(c4);


        //是否可以查看审批记录
        CustomProperty c5 = new CustomProperty();
        c5.setName("actapprovalrecord");
        c5.setSimpleValue(getPropertyValueAsString("actapprovalrecord", elementNode));
        customProperty.add(c5);

        //是否可以配置审批记录权限
        CustomProperty c6 = new CustomProperty();
        c6.setName("actrecordpermissions");
        c6.setSimpleValue(getPropertyValueAsString("actrecordpermissions", elementNode));
        customProperty.add(c6);

        //默认抄送人
        CustomProperty c7 = new CustomProperty();
        c7.setName("ccusers");
        c7.setSimpleValue(getPropertyValueAsString("ccusers", elementNode));
        customProperty.add(c7);


        //是否可以查看流程图
        CustomProperty c8 = new CustomProperty();
        c8.setName("actapprovalpng");
        c8.setSimpleValue(getPropertyValueAsString("actapprovalpng", elementNode));
        customProperty.add(c8);

        //是否可以ABA跳
        CustomProperty c9 = new CustomProperty();
        c9.setName("skiptaskaba");
        c9.setSimpleValue(getPropertyValueAsString("skiptaskaba", elementNode));
        customProperty.add(c9);

        //是否可以批量处理
        CustomProperty c10 = new CustomProperty();
        c10.setName("batch");
        c10.setSimpleValue(getPropertyValueAsString("batch", elementNode));
        customProperty.add(c10);

        //是否可以加签
        CustomProperty c11 = new CustomProperty();
        c11.setName("actaddtask");
        c11.setSimpleValue(getPropertyValueAsString("actaddtask", elementNode));
        customProperty.add(c11);

        //是否为结束节点
        CustomProperty c12 = new CustomProperty();
        c12.setName("endnode");
        c12.setSimpleValue(getPropertyValueAsString("endnode", elementNode));
        customProperty.add(c12);

        //是否为投票节点
        CustomProperty c13 = new CustomProperty();
        c13.setName("isvote");
        c13.setSimpleValue(getPropertyValueAsString("isvote", elementNode));
        customProperty.add(c13);


        //节点日文名称
        CustomProperty c14 = new CustomProperty();
        c14.setName("jajpname");
        c14.setSimpleValue(getPropertyValueAsString("jajpname", elementNode));
        customProperty.add(c14);


        //节点英文名称
        CustomProperty c15 = new CustomProperty();
        c15.setName("enusname");
        c15.setSimpleValue(getPropertyValueAsString("enusname", elementNode));
        customProperty.add(c15);

        //节点繁体名称
        CustomProperty c16 = new CustomProperty();
        c16.setName("zhtwname");
        c16.setSimpleValue(getPropertyValueAsString("zhtwname", elementNode));
        customProperty.add(c16);

        //是否为下一阶段选择审批人
        CustomProperty c17 = new CustomProperty();
        c17.setName("selectapproval");
        c17.setSimpleValue(getPropertyValueAsString("selectapproval", elementNode));
        customProperty.add(c17);

        //是否需要申请人选择审批人
        CustomProperty c18 = new CustomProperty();
        c18.setName("applychoice");
        c18.setSimpleValue(getPropertyValueAsString("applychoice", elementNode));
        customProperty.add(c18);

        //可以查看审批意见的角色
        CustomProperty c19 = new CustomProperty();
        c19.setName("viewcommentrole");
        c19.setSimpleValue(getPropertyValueAsString("viewcommentrole", elementNode));
        customProperty.add(c19);

        //是否为流程结束节点
        CustomProperty c20 = new CustomProperty();
        c20.setName("endtasknode");
        c20.setSimpleValue(getPropertyValueAsString("endtasknode", elementNode));
        customProperty.add(c20);


        // 审批时是否可以上传附件
        CustomProperty c21 = new CustomProperty();
        c21.setName("uploadfile");
        c21.setSimpleValue(getPropertyValueAsString("uploadfile", elementNode));
        customProperty.add(c21);


        // 前加签的任务是否可以驳回
        CustomProperty c22 = new CustomProperty();
        c22.setName("addbeforetaskrejected");
        c22.setSimpleValue(getPropertyValueAsString("addbeforetaskrejected", elementNode));
        customProperty.add(c22);

        // 是否是电子签章的签约节点
        CustomProperty c23 = new CustomProperty();
        c23.setName("electronicseal");
        c23.setSimpleValue(getPropertyValueAsString("electronicseal", elementNode));
        customProperty.add(c23);

        // 申请人选择审批人的范围(可配置角色标识，多个逗号加个)
        CustomProperty c24 = new CustomProperty();
        c24.setName("applychoicescope");
        c24.setSimpleValue(getPropertyValueAsString("applychoicescope", elementNode));
        customProperty.add(c24);

        // 表单属性获取脚本
        CustomProperty c25 = new CustomProperty();
        c25.setName("formsql");
        c25.setSimpleValue(getPropertyValueAsString("formsql", elementNode));
        customProperty.add(c25);

        task.setCustomProperties(customProperty);

//        ActMessage actMessage = new ActMessage();
//        actMessage.setActId(getPropertyValueAsString("overrideid", elementNode));
//        actMessage.setEnUs(getPropertyValueAsString("enusname", elementNode));
//        actMessage.setZhTw(getPropertyValueAsString("zhtwname", elementNode));
//        actMessage.setJaJp(getPropertyValueAsString("jajpname", elementNode));
//        actMessage.setProcDefId(getPropertyValueAsString("process_id", modelNode));
//        actMessageService.save(actMessage);


        JsonNode assignmentNode = getProperty(PROPERTY_USERTASK_ASSIGNMENT, elementNode);
        if (assignmentNode != null) {
            JsonNode assignmentDefNode = assignmentNode.get("assignment");
            if (assignmentDefNode != null) {

                JsonNode assigneeNode = assignmentDefNode.get(PROPERTY_USERTASK_ASSIGNEE);
                if (assigneeNode != null && assigneeNode.isNull() == false) {
                    task.setAssignee(assigneeNode.asText());
                }

                JsonNode ownerNode = assignmentDefNode.get(PROPERTY_USERTASK_OWNER);
                if (ownerNode != null && ownerNode.isNull() == false) {
                    task.setOwner(ownerNode.asText());
                }

                task.setCandidateUsers(getValueAsList(PROPERTY_USERTASK_CANDIDATE_USERS, assignmentDefNode));
                task.setCandidateGroups(getValueAsList(PROPERTY_USERTASK_CANDIDATE_GROUPS, assignmentDefNode));
            }
        }
        convertJsonToFormProperties(elementNode, task);
        return task;
    }
}
